package com.caigou.service.impl;

import com.caigou.bean.cms.entity.SystemMessage;
import com.caigou.bean.cms.param.SystemMessageParam;
import com.caigou.bean.cms.param.SystemMessageQueryParam;
import com.caigou.bean.exam.entity.Users;
import com.caigou.component.RedisComponent;
import com.caigou.component.RedisObjectComponent;
import com.caigou.component.SnowflakeComponent;
import com.caigou.constant.NewsConstant;
import com.caigou.enums.Constant;
import com.caigou.mapper.cms.SystemMessageMapper;
import com.caigou.mapper.exam.UsersMapper;
import com.caigou.service.SystemMessageService;
import com.caigou.util.Result;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service("systemMessageService")
public class SystemMessageServiceImpl implements SystemMessageService {

    @Resource
    private SnowflakeComponent snowflakeComponent;// 雪花UUID组件

    @Resource
    private SystemMessageMapper systemMessageMapper;

    @Resource
    private UsersMapper usersMapper;

    @Resource
    private RedisComponent redisComponent;

    @Resource
    private RedisObjectComponent redisObjectComponent;

    public Long getMessageId(){
        long messageId = snowflakeComponent.getInstance().nextId();
        return messageId;
    }

    /**
     * 创建系统推送消息
     * @param systemMessageParam
     * @return
     */
    public Result saveSystemMessage(SystemMessageParam systemMessageParam, Users user){
        SystemMessage systemMessage = new SystemMessage();
        systemMessage.setMessageId(systemMessageParam.getMessageId());
        systemMessage.setMessageTitle(systemMessageParam.getMessageTitle());
        systemMessage.setPublishType(systemMessageParam.getPublishType());
        systemMessage.setCreateUserId(systemMessageParam.getCreateUserId());
        systemMessage.setMessageContent(systemMessageParam.getMessageContent());
        systemMessage.setPublishStatus(systemMessageParam.getPublishStatus());
        systemMessage.setPublishUserId(user.getUserid());
        long timestamp = System.currentTimeMillis();
        Date currentTime = new Date(timestamp);
        if(systemMessageParam.getPublishType()==0 && systemMessageParam.getPublishStatus()==2){//发布方式：即时，发布状态：已发布
            systemMessage.setPublishTime(currentTime);
            int receiveUserCount = usersMapper.getReceiveSystemMessageUserCount(new Long(timestamp/1000).intValue());
            systemMessage.setReceiveUserCount(receiveUserCount);
        }else if(systemMessageParam.getPublishType()==1 && systemMessageParam.getPublishStatus()==1){//发布方式：定时，发布状态：未发布
            if(timestamp>systemMessageParam.getPublishTime().getTime()){//当前时间大于发布时间，主动将发布时间设置为“当前时间”，发布状态设置为“已发布”
                systemMessage.setPublishTime(currentTime);
                systemMessage.setPublishStatus(2);
                int receiveUserCount = usersMapper.getReceiveSystemMessageUserCount(new Long(timestamp/1000).intValue());
                systemMessage.setReceiveUserCount(receiveUserCount);
            }else {
                systemMessage.setPublishTime(systemMessageParam.getPublishTime());
            }
        }
        systemMessage.setCreateTime(currentTime);
        systemMessage.setUpdateTime(currentTime);
        int count = systemMessageMapper.insertSelective(systemMessage);
        log.info("保存系统消息结果count={}, publishType={}, publishStatus={}", count, systemMessageParam.getPublishType(), systemMessageParam.getPublishStatus());
        if(count>0){
            if (systemMessageParam.getPublishType()==1 && systemMessageParam.getPublishStatus()==1){//发布方式：定时，发布状态：待发布（未发布）
                long publishTimestamp = systemMessageParam.getPublishTime().getTime();
                //redis中过期时间
                long expireTime = (publishTimestamp-timestamp)/1000;
                if(expireTime>0){
                    String systemMessageKey = NewsConstant.SYSTEM_MESSAGE_PRE_KEY+systemMessage.getId();
                    //向redis中设置该key的过期时间
                    boolean result = redisComponent.set(systemMessageKey, systemMessageKey, expireTime);
                    log.info("set to redis result={}, systemMessageKey={}, expireTime={}", result, systemMessageKey, expireTime);
                }
            }
            return Result.success("创建系统消息成功");
        }else{
            return Result.custom(400, "创建系统消息失败", "创建系统消息失败");
        }
    }


    /**
     *
     * @param systemMessageParam
     * @return
     */
    public Result updateSystemMessage(SystemMessageParam systemMessageParam, Users user){
        SystemMessage systemMessage = new SystemMessage();
        systemMessage.setId(systemMessageParam.getId());
        systemMessage.setMessageTitle(systemMessageParam.getMessageTitle());
        systemMessage.setMessageContent(systemMessageParam.getMessageContent());
        systemMessage.setPublishType(systemMessageParam.getPublishType());
        systemMessage.setPublishUserId(user.getUserid());
        systemMessage.setPublishStatus(systemMessageParam.getPublishStatus());
        long timestamp = System.currentTimeMillis();
        Date currentTime = new Date(timestamp);
        //发布方式publishType：即时发布（0），发布状态publishStatus：已发布（2）
        if(systemMessageParam.getPublishType()==0 && systemMessageParam.getPublishStatus()==2){
            systemMessage.setPublishTime(currentTime);
            int receiveUserCount = usersMapper.getReceiveSystemMessageUserCount(new Long(timestamp/1000).intValue());
            systemMessage.setReceiveUserCount(receiveUserCount);
        }else if(systemMessageParam.getPublishType()==1 && systemMessageParam.getPublishStatus()==1){
            if(timestamp>systemMessageParam.getPublishTime().getTime()){//当前时间大于发布时间，主动将发布时间设置为“当前时间”，发布状态设置为“已发布”
                systemMessage.setPublishTime(currentTime);
                systemMessage.setPublishStatus(2);
                int receiveUserCount = usersMapper.getReceiveSystemMessageUserCount(new Long(timestamp/1000).intValue());
                systemMessage.setReceiveUserCount(receiveUserCount);
            }else {
                systemMessage.setPublishTime(systemMessageParam.getPublishTime());
            }
        }
        systemMessage.setUpdateTime(currentTime);
        int count = systemMessageMapper.updateSystemMessage(systemMessage);
        if(count>0){
            if (systemMessageParam.getPublishType()==1 && systemMessageParam.getPublishStatus()==1){//发布方式：定时，发布状态：待发布（未发布）
                long publishTimestamp = systemMessageParam.getPublishTime().getTime();
                //redis中过期时间
                long expireTime = (publishTimestamp-timestamp)/1000;
                if(expireTime>0){
                    String systemMessageKey = NewsConstant.SYSTEM_MESSAGE_PRE_KEY+systemMessage.getId();
                    //向redis中设置该key的过期时间
                    boolean result = redisComponent.set(systemMessageKey, systemMessageKey, expireTime);
                    log.info("set to redis result={}, systemMessageKey={}, expireTime={}", result, systemMessageKey, expireTime);
                }
            }
            return Result.success("修改系统消息成功");
        }else{
            return Result.custom(300, "修改系统消息失败", "修改系统消息失败");
        }
    }

    /**
     * 定时自动发布系统消息
     * @param id
     * @return
     */
    public int autoPublishSystemMessage(int id){
        SystemMessage systemMessage = new SystemMessage();
        systemMessage.setId(id);
        systemMessage.setPublishStatus(2);
        systemMessage.setUpdateTime(new Date(System.currentTimeMillis()));
        int count = systemMessageMapper.updateSystemMessage(systemMessage);
        return count;
    }

    public PageInfo<SystemMessage> querySystemMessage(SystemMessageQueryParam systemMessageQueryParam){
        Long intKeyword = null;
        try{
            intKeyword = Long.parseLong(systemMessageQueryParam.getKeyword());
            systemMessageQueryParam.setIntKeyword(intKeyword);
        }catch(Exception e){
            //log.error(e.getMessage(), e);
        }
        Page<?> page = PageHelper.startPage(systemMessageQueryParam.getPageNum(), systemMessageQueryParam.getPageSize());
        List<SystemMessage> systemMessagesList = systemMessageMapper.querySystemMessage(systemMessageQueryParam);
        systemMessagesList.stream().peek(systemMessage -> systemMessage.setStrMessageId(systemMessage.getMessageId().toString())).collect(Collectors.toList());
        PageInfo<SystemMessage> pageInfoSystemMessage = new PageInfo<SystemMessage>(systemMessagesList);
        return pageInfoSystemMessage;
    }

    public SystemMessage selectByPrimaryKey(Integer id){
        return systemMessageMapper.selectByPrimaryKey(id);
    }

    public SystemMessage selectByMessageId(Long messageId){
        return systemMessageMapper.selectByMessageId(messageId);
    }

    public int deleteByPrimaryKey(Integer id){
        return systemMessageMapper.deleteByPrimaryKey(id);
    }

    public int deleteByMessageId(Long messageId){
        return systemMessageMapper.deleteByMessageId(messageId);
    }

    /**
     * 撤回系统消息
     * @param id
     * @return
     */
    public int withdrawSystemMessage(Integer id){
        SystemMessage systemMessage = new SystemMessage();
        systemMessage.setId(id);
        systemMessage.setPublishStatus(3);//3发布状态撤回
        systemMessage.setUpdateTime(new Date(System.currentTimeMillis()));
        return systemMessageMapper.updateSystemMessage(systemMessage);
    }

    /**
     * 消息中心--我的消息列表页，支持分页
     * @param pageNum
     * @param pageSize
     * @return
     */
    public PageInfo<SystemMessage> listMyMessage(String userId, Integer pageNum, Integer pageSize){
        PageHelper.startPage(pageNum, pageSize);
        List<SystemMessage> systemMessagesList = systemMessageMapper.listMyMessage();
        String key = String.format(Constant.MY_READ_MESSAGE_KEY, userId);
        systemMessagesList.forEach(systemMessage -> {
            //设置strMessageId
            String strMessageId = systemMessage.getMessageId().toString();
            systemMessage.setStrMessageId(strMessageId);
            //设置已读/未读标识
            boolean readFlog = redisObjectComponent.sHasKey(key, String.valueOf(systemMessage.getMessageId()));
            log.info("userId={}, messageId={}, readFlag={} from redis", userId, systemMessage.getMessageId(), readFlog);
            systemMessage.setRead(readFlog);
                });
        PageInfo<SystemMessage> pageInfoSystemMessage = new PageInfo<SystemMessage>(systemMessagesList);
        return pageInfoSystemMessage;
    }

    /**
     * 获取并读取系统消息，即将该用户对此系统消息的已读状态设置为已读，redis的set实现
     * @param userId
     * @param messageId
     * @return
     */
    public SystemMessage getAndReadSystemMessage(String userId, Long messageId){
        String key = String.format(Constant.MY_READ_MESSAGE_KEY, userId);
        long count = redisObjectComponent.sSet(key, String.valueOf(messageId));
        log.info("userId={}， messageId={}向redis设置set结果={}", userId, messageId, count);
        return systemMessageMapper.selectByMessageId(messageId);
    }
}
